Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dash App with Multiple Flask Routes #70

Merged
merged 1 commit into from
Jul 10, 2017
Merged

Conversation

rc1405
Copy link

@rc1405 rc1405 commented Jul 5, 2017

Modified flask endpoints to allow for multiple routes to be added to the Flask server, such as serving multiple Dash apps, or additional content. Simple example below.

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
from flask import Flask

server = Flask("my app")

app2 = dash.Dash(name='place1', sharing=True, server=server, url_base_pathname='/test1')

app2.layout = html.Div([
        html.H1('This is a test1')
    ])

app3 = dash.Dash(name='place2', sharing=True, server=server, url_base_pathname='/test2')

app3.layout = html.Div([
        html.H1('This is test2')
    ])

server.run(port=80, host='0.0.0.0')

@Volodymyrk
Copy link

Interesting.. I've open a PR just one hour before you did to address a similar use-case.
Your solution is actually better.

I've just tested it with this structure, and it works well:

server.py

from flask import Flask

server = Flask(__name__)

app1.py

import dash

from server import server

app = dash.Dash(name='app1', sharing=True, server=server, url_base_pathname='/app1')

app2.py

import dash

from server import server

app = dash.Dash(name='app2', sharing=True, server=server, url_base_pathname='/app2')

run.py

from server import server

from app1  import app as app1
from app2 import app as app2

if __name__ == '__main__':
    server.run()

@rc1405
Copy link
Author

rc1405 commented Jul 5, 2017

Haha, yeah I saw your PR after I committed the changes, and was a bit confused about how I missed it until I looked at the time stamp. I thought the implementation was different enough to throw some more options out there.

@chriddyp
Copy link
Member

This is pretty cool! I like this. I don't see any drawbacks to this. Will using endpoint bite us down the line in any way?

@chriddyp
Copy link
Member

For a related topic on multi-page URLs, check out #77

@cnblevins
Copy link

I am looking at the structure that is coming together here and wondering how the selective authorization use-case can be implemented...
I must be dense, because I am still trying to piece together the dash equivalent for the following (one dyno yielding a publicly accessible app1 "page" and a restricted-access app2 "page")...

[...]
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
[...]

(at)app.route('/app1')
[...]

(at)app.route('/app2')
(at)login_required
[...]

@rc1405
Copy link
Author

rc1405 commented Jul 10, 2017

I haven't seen any drawbacks to using endpoint, from what I've seen and the related docs is that it changes how the function is stored. By default, it is stored by function name which causes a conflict when you try to store the same name twice unless it is the same object as with the authentication.

@rc1405
Copy link
Author

rc1405 commented Jul 10, 2017

#77 fits my use case better, although I can picture environments where they might be need to be separate

@Volodymyrk
Copy link

#77 does not help my use-case.
I am planning to build multiple, independent apps and I don't to simplify the deployment/management. I would not have any links between them, but I want those apps to have different URLs, so they can be embedded into iframes in the intranet portal.
I would like this to be merged into master, if no-one found a problem with endpoints.

@chriddyp
Copy link
Member

I want those apps to have different URLs, so they can be embedded into iframes in the intranet portal.

FWIW, #77 allows you to do this as well:

app.layout = html.Div([
    dcc.Location(id='location'),
    html.Div(id='content')
])

@app.callback(Output('content', 'children'), [Input('location', 'pathname')])
def display_page(pathname):
    if pathname == '/':
         return app1.layout
    elif pathname == '/app-2':
         return app2.layout
    # [...]

@chriddyp
Copy link
Member

This looks good to me though. Thanks @rc1405 and @Volodymyrk !

@chriddyp chriddyp merged commit 81dcb12 into plotly:master Jul 10, 2017
@Volodymyrk
Copy link

@chriddyp what happens with callbacks in app1 and app2 ?
In my quick test - they disappear, since they were not registered in app..
#70 is addressing this. However, I can't get it to work with a proper webserver (gunicorn)

chriddyp added a commit that referenced this pull request Sep 8, 2017
This was accidentely removed in a git merge
@chriddyp chriddyp mentioned this pull request Sep 8, 2017
chriddyp added a commit that referenced this pull request Sep 8, 2017
This was accidentely removed in a git merge
sbvhev added a commit to sbvhev/dash that referenced this pull request Mar 12, 2018
This was accidentely removed in a git merge
@brylie
Copy link

brylie commented Oct 1, 2018

Wow! Is this in the docs? I have been searching around and only came to this PR from a lengthy discussion thread.

@sidd-hart
Copy link

Has anyone tried to implement flask-login with this solution. It doesn't seem to be working for me. Would be very helpful if anyone could suggest a solution to implement flask-login.

denis554 added a commit to denis554/dash that referenced this pull request Apr 9, 2019
This was accidentely removed in a git merge
byronz pushed a commit that referenced this pull request Apr 23, 2019
Update circle to version 2.
HammadTheOne pushed a commit to HammadTheOne/dash that referenced this pull request May 28, 2021
Rebuild components with Python3.7 (remove `async` keyword).
HammadTheOne pushed a commit to HammadTheOne/dash that referenced this pull request May 28, 2021
* fix regression + basic test

* build.watch, not test

* remove .only on tests...

* fix copy test

* add back cypress issue comment

* - copy/paste with sorting
- delete cell with and w/o sorting
- additional tests for copy/paste

* - delete cell tests for sorted and sorted df

* fix saving changes on click outside of cell

* update changelog

* fix useless propagates on click outside / blur
HammadTheOne pushed a commit that referenced this pull request Jul 23, 2021
* fix regression + basic test

* build.watch, not test

* remove .only on tests...

* fix copy test

* add back cypress issue comment

* - copy/paste with sorting
- delete cell with and w/o sorting
- additional tests for copy/paste

* - delete cell tests for sorted and sorted df

* fix saving changes on click outside of cell

* update changelog

* fix useless propagates on click outside / blur
HammadTheOne pushed a commit that referenced this pull request Jul 23, 2021
Rebuild components with Python3.7 (remove `async` keyword).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants